home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group00b.txt / 000117_icon-group-sender_Fri Oct 27 08:22:34 2000.msg < prev    next >
Internet Message Format  |  2001-01-03  |  3KB

  1. Return-Path: <icon-group-sender>
  2. Received: (from root@localhost)
  3.     by baskerville.CS.Arizona.EDU (8.11.1/8.11.1) id e9RFMNB20153
  4.     for icon-group-addresses; Fri, 27 Oct 2000 08:22:23 -0700 (MST)
  5. Message-Id: <200010271522.e9RFMNB20153@baskerville.CS.Arizona.EDU>
  6. X-Sender: whm@mail.mse.com
  7. Date: Fri, 27 Oct 2000 01:44:04 -0700
  8. To: icon-group@cs.arizona.edu
  9. From: "William H. Mitchell" <whm@mse.com>
  10. Subject: Re: Yet another Newbie question....
  11. Errors-To: icon-group-errors@cs.arizona.edu
  12. Status: RO
  13. Content-Length: 2366
  14.  
  15. This approach comes up from time to time on this list, but for the
  16. scanning-challenged a lot of text parsing can be done with a procedure that
  17. breaks apart strings at delimeters.  Lots of folks have written such a
  18. thing.  The one I wrote is called split, perhaps after the p*rl analog -- I
  19. forget.  A clipping about split from some lecture notes I wrote on Icon
  20. follows below.  Note that the pairs of lines beginning with "][" are
  21. interaction with an Icon expression evaluator.
  22.  
  23. -----------
  24.  
  25. The procedure split(s, delims) returns a list consisting of the portions of
  26. the string s delimited by characters in delims:
  27.  
  28. ][ split("just a test here ", ' ');
  29.    r := L1:["just","a","test","here"]  (list)
  30.  
  31. ][ split("...1..3..45,78,,9 10  ", '., ');
  32.    r := L1:["1","3","45","78","9","10"]  (list)
  33.  
  34.  
  35. Consider a file whose lines consist of zero or more integers separated by
  36. white space:
  37.  
  38. 5 10 0
  39. 100 50
  40.  
  41. 200
  42. 1 2 3 4 5 6 7 8 9 10
  43.  
  44.  
  45. A program to sum the numbers in such a file:
  46.  
  47. link split
  48. procedure main()
  49.     sum := 0
  50.     while line := read() do {
  51.         nums := split(line, ' \t')
  52.         every num := !nums do
  53.             sum +:= num
  54.         }
  55.  
  56.     write("The sum is ", sum)
  57. end
  58.  
  59. If split has a third argument that is non-null, both delimited and
  60. delimiting pieces of the string are produced:
  61.  
  62. ][ split("520-621-6613", '-', 1);
  63.    r := L1:["520","-","621","-","6613"]  (list)
  64.  
  65. A sequence of splits: 
  66. s := "a.b x.y p.q";
  67. L1 := split(s, ' ');
  68. L2 := split(L1[2], '.');
  69.  
  70. ----------
  71.  
  72. Here's the source for split:
  73.  
  74. #
  75. # split(s, delimiters, keepall) splits the string s into consecutive substrings
  76. #  that do/do not consist of characters in the cset delimiters, producing a
  77. #  list of strings.  If keepall is null, strings consisting delimiters are not
  78. #  included in the result list.
  79. #
  80. # If not specified, delimeters defaults to blank and tab, which essentially
  81. # "tokenizes" non-whitespace:
  82. #
  83. #   words := split(read())
  84. #
  85. # Author: William H. Mitchell (whm@mse.com) c. 1996
  86. #
  87. procedure split(s, dlms, keepall)
  88.    local w, ws, addproc, nullproc
  89.  
  90.    ws := []
  91.    /dlms := " \t"
  92.    
  93.    addproc := put
  94.    if \keepall then
  95.       otherproc := put
  96.    else
  97.       otherproc := 1
  98.    
  99.    if dlms := (any(dlms, s[1]) & ~dlms) then
  100.       otherproc :=: addproc
  101.     
  102.    s ? while w := tab(many(dlms := ~dlms)) do {
  103.       addproc(ws, w)
  104.       otherproc :=: addproc
  105.       }
  106.  
  107.    return ws
  108. end
  109.  
  110.